package com.amumu.drama.common.modules.service.impl.payment.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.amumu.drama.common.constant.*;
import com.amumu.drama.common.exception.Asserts;
import com.amumu.drama.common.modules.alipay.dto.AjaxResult;
import com.amumu.drama.common.modules.alipay.dto.AliPayBean;
import com.amumu.drama.common.modules.alipay.dto.req.AliNotifyReq;
import com.amumu.drama.common.modules.order.dao.PortalOrderDao;
import com.amumu.drama.common.modules.order.dto.OmsOrderDetail;
import com.amumu.drama.common.modules.order.manager.OrderManager;
import com.amumu.drama.common.modules.order.service.OmsPortalOrderService;
import com.amumu.drama.common.modules.service.impl.payment.PaymentFactory;
import com.amumu.drama.common.modules.service.impl.payment.PaymentReq;
import com.amumu.drama.common.modules.service.impl.payment.PaymentResp;
import com.amumu.drama.model.OmsOrder;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class AliPaymentHandler implements PaymentHandler {

    private final AjaxResult result = new AjaxResult();

    // 普通公钥模式
//     private final static String NOTIFY_URL = "/aliPay/notify_url";
    /**
     * 证书模式
     */
    private final static String NOTIFY_URL = "/aliPay/cert_notify_url";
//    private final static String RETURN_URL = "/aliPay/return_url";
    /**
     * 证书模式
     */
    private final static String RETURN_URL = "/aliPay/cert_return_url";

    @Override
    public String[] type() {
        return new String[]{
                PaymentFactory.getPayHandlerType(PayTypeEnum.ALI_PAY, PayProviderEnum.ALI_PAY, SourceTypeEnum.UNKNOWN),
                PaymentFactory.getPayHandlerType(PayTypeEnum.ALI_PAY, PayProviderEnum.ALI_PAY, SourceTypeEnum.APP),
                PaymentFactory.getPayHandlerType(PayTypeEnum.ALI_PAY, PayProviderEnum.ALI_PAY, SourceTypeEnum.PC),
        };
    }


    @Autowired
    private OrderManager orderManager;

    @Resource
    private AliPayBean aliPayBean;

    @Autowired
    private AliPayApiConfig aliPayApiConfig;

    @Autowired
    private PortalOrderDao portalOrderDao;

    @Autowired
    private OmsPortalOrderService omsPortalOrderService;

    @Override
    public PaymentResp pay(PaymentReq param) {
        OmsOrderDetail orderDetail = param.getOrderDetail();
        log.info("支付宝支付开始:orderId:{}", param.getOrderId());
        PaymentResp resp = new PaymentResp();
        resp.setApplyTime(LocalDateTime.now());
        String body = "微丸子科技有限公司";
        String subject = orderDetail.getOrderItemList().get(0).getProductName();
        String totalAmount = orderDetail.getPayAmount().toString();
        String passBackParams = "1";
        String returnUrl = aliPayBean.getDomain() + RETURN_URL;
        String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setBody(body);
        model.setSubject(subject);
        model.setTotalAmount(totalAmount);
        model.setPassbackParams(passBackParams);
        model.setOutTradeNo(orderDetail.getOrderSn());
        model.setProductCode("QUICK_WAP_PAY");
        resp.setReqInfo(JSONUtil.toJsonStr(model));
        try {
            String result = AliPayApi.wapPayStr(aliPayApiConfig.getAliPayClient(), model, returnUrl, notifyUrl);
            log.info(result);
            resp.setRespInfo(result);
            resp.setPayStatusEnum(PayStatusEnum.PAYING);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("支付宝支付失败：", e);
            resp.setPayStatusEnum(PayStatusEnum.FAIL);
            resp.setPayRemark("支付失败：" + e.getMessage());
        }
        return resp;
    }


    @Override
    public PaymentResp payNotify(Map<String, String> params, String body) {
        PaymentResp paymentResp = new PaymentResp();
        paymentResp.setPayRemark("success");
        // 获取支付宝POST过来反馈信息
//        Map<String, String> params = AliPayApi.toMap(request);

        for (Map.Entry<String, String> entry : params.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }


        boolean verifyResult = false;
        try {
            verifyResult = AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2");
            if (!verifyResult) {
                log.error("支付宝回调验签失败：request:{}", JSONUtil.toJsonStr(params));
                return paymentResp;
            }
        } catch (AlipayApiException e) {
            log.error("支付宝回调验签失败", e);
            return paymentResp;
        }
        log.info("支付宝回调验签成功");
        JSONObject jsonObject = JSONUtil.parseObj(params);
        if (jsonObject == null) {
            return paymentResp;
        }
        AliNotifyReq notifyReq = jsonObject.toBean(AliNotifyReq.class);
        if (notifyReq == null) {
            return paymentResp;
        }

        String orderSn = notifyReq.getOutTradeNo();
        OmsOrder orderDetail = omsPortalOrderService.queryOrderByOrderSn(orderSn);
        if (orderDetail == null) {
            log.error("order {} not exist!", orderSn);
            Asserts.fail("订单不存在");
        }
        if (!Objects.equals(orderDetail.getPayStatus(), PayStatusEnum.PAYING.getCode())) {
            log.error("order {} status {} invalid", orderDetail.getId(), orderDetail.getStatus());
            Asserts.fail("订单状态不正确,无法支付");
        }
        try {
            Integer payType = orderDetail.getPayType();
            if (payType == null) {
                log.error("支付类型不能为空,paymentType={},params={},body:{}，", payType, params, body);
                Asserts.fail("支付类型不能为空");
            }

            String tradeStatus = notifyReq.getTradeStatus();
            if (StrUtil.isBlank(tradeStatus)) {
                log.error("回调参数状态不能为空,paymentType={},payStatus={}", payType, tradeStatus);
                Asserts.fail("回调参数不能为空");
            }
            if (AlipayTradeStatusEnum.TRADE_SUCCESS.getCode().equals(tradeStatus)) {
                paymentResp.setPayStatusEnum(PayStatusEnum.SUCCESS);
            } else {
                paymentResp.setPayStatusEnum(PayStatusEnum.FAIL);
            }

        } catch (Exception e) {
            log.error("支付宝回调处理结果异常", e);
            paymentResp.setPayStatusEnum(PayStatusEnum.FAIL);
            paymentResp.setPayRemark(e.getMessage());
            return paymentResp;
        }
        return paymentResp;
    }
}
